/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: Frank
 * 系统版本: 1.0.0
 * 开发人员: Frank
 * 开发时间: 2019/12/12 11:17
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.uaa.service;

import com.spring.arch.common.enums.UserStatus;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.uaa.enums.Constant;
import com.spring.arch.uaa.errorcode.UaaErrorCode;
import com.spring.arch.uaa.model.TenantEmployee;
import com.spring.arch.uaa.model.User;
import com.spring.arch.uaa.repository.UserRepository;
import com.spring.arch.common.enums.UserStatus;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.uaa.enums.Constant;
import com.spring.arch.uaa.model.TenantEmployee;
import com.spring.arch.uaa.model.User;
import com.spring.arch.uaa.repository.TenantEmployeeRepository;
import com.spring.arch.uaa.repository.UserRepository;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static com.spring.arch.uaa.errorcode.UaaErrorCode.*;

/**
 * 用户服务层接口
 *
 * @author Frank
 * @version 1.0.0.1
 * @since 2019/12/12 11:17
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class UserService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private TenantEmployeeRepository tenantEmployeeRepository;

    public User save(User model) {
        return userRepository.save(model);
    }

    public User createUser(TenantEmployee employee) {
        // 查询手机号
        Optional<User> optional = userRepository.findByMobile(employee.getMobile());
        if (!optional.isPresent()) {
            User user = new User();
            user.setMobile(employee.getMobile());
            user.setRealName(employee.getName());
            // 生成随机盐
            String salt = RandomStringUtils.randomAlphabetic(6);
            String pwd = passwordEncoder.encode(StringUtils.joinWith("$", Constant.GLOBAL_DEFAULT_PASSWORD, salt));
            user.setPassword(pwd);
            user.setSalt(salt);
            user.setEmail(employee.getEmail());
            user.setGender(employee.getGender());
            user.setStatus(UserStatus.ACTIVE);
            return userRepository.save(user);
        }
        return optional.get();
    }

    public void delete(UUID id) {
        final User user = userRepository.findById(id)
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001001001, String.valueOf(id)));
        user.setStatus(UserStatus.DELETED);
        userRepository.save(user);
    }

    /**
     * 锁定|解锁操作
     * @param id 用户实体ID
     */
    public void lock(UUID id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001005001, String.valueOf(id)));
        if (user.isEnabled()) {
            user.setStatus(UserStatus.LOCKED);
        } else if (UserStatus.LOCKED.equals(user.getStatus())) {
            user.setStatus(UserStatus.ACTIVE);
        } else {
            throw ExceptionHolder.serviceException(UaaErrorCode.E2001005004);
        }
        userRepository.save(user);
    }

    public void resetPassword(String mobile, String password) {
        User user = userRepository.findByMobile(mobile).orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001005001, mobile));
        // 用户密码加密
        String pwd = passwordEncoder.encode(StringUtils.joinWith("$", password.trim(), user.getSalt()));
        user.setPassword(pwd);
        // 保存用户
        userRepository.save(user);
    }

    public void resetMobile(String mobile, String newMobile) {
        // 校验新密码
        Optional<User> optional = userRepository.findByMobile(newMobile);
        if (optional.isPresent()) {
            throw ExceptionHolder.serviceException(UaaErrorCode.E2001005009, newMobile);
        }
        User user = userRepository.findByMobile(mobile).orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001005001, mobile));
        user.setMobile(newMobile);
        // 保存用户
        userRepository.save(user);
        // 更新人员手机号
        List<TenantEmployee> employees = tenantEmployeeRepository.findByMobile(mobile);
        if (!CollectionUtils.isEmpty(employees)) {
            employees.forEach(e -> {
                e.setMobile(newMobile);
                tenantEmployeeRepository.save(e);
            });
        }
    }
}
